ICTSC2019 二次予選 問題解説: 君k8s得意って言っていたよね?
問題文
職場でkubernetesを用いてRedmineを導入することになった。
上司が構築作業をしていたが、どうもうまくRedmineが起動しないらしい。
部下のあなたがk8sが得意ということだったので、構築作業の続きをすることになった。
kubernetesが動作するサーバーにRedmine用のManifestが適用されているが、どうも正常起動していないようだ。
原因を究明を行い、Redmineを使える状態にして解決方法を報告してください。
問題のゴール
- VNCクライアントのブラウザからRedmineが閲覧できること。
http://192.168.0.100:30000
- Redmineのデータがコンテナ再起動時にも保持されていること。
情報
- Server:
- k8smaster1:
- ip: 192.168.0.100
- userid: root
- password: USerPw@19
- container-registry:
- ip: 192.168.0.101
- 備考: 操作不可
- Redmine_Manifest:
- path: “/root/ictsc_problem_manifests/*.yaml”
- Redmineログイン情報
- userid: ictsc
- password: USerPw@19
制限事項
- Redmineは指定のManifest(Redmine_Manifest)でデプロイしてください。
- Redmine_Manifestは変更出来ません。
- Redmine_Manifest内のコンテナイメージはcontainer-registryから取得してください。
- マニフェストの再適用, OSの再起動の操作は可能です。
- 誤操作等で競技続行不可の場合は出題時環境への復元のみ承ります。
Kubernetes上にRedmineサービスを稼働させる問題です。
出題時にはRedmineを構成するRedmine-Pod, MariaDB-PodがPending
となっており、利用不可の状態です。
コンテナが稼働しない原因を突き止め対処することでRedmineサービスを稼働させることができます。
問題解決のために以下の原因を解決する必要があります。
- masterへpodのデプロイに関するtaintsの削除
- コンテナランタイムcri-oにinsecure-registryの設定を追加
- MariaDBのPersistentVolumeのディレクトリ権限(Permission)を修正
問題解説
Kubernetes上にRedmineサービスを稼働させる問題です。
出題時にはRedmineを構成するRedmine-Pod, MariaDB-PodがPending
となっており、利用不可の状態です。
コンテナが稼働しない原因を突き止め対処することでRedmineサービスを稼働させることができます。
masterへpodのデプロイに関するtaintsの削除
kubectl get pod
でコンテナの状態を見ます。
[root@k8smaster1 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
my-release-mariadb-0 0/1 Pending 0 9d
my-release-redmine-859cf77958-n95j5 0/1 Pending 0 9d
redmineとmariadbがpending
になっています。
kubectl describe pod <pod名>
で各Podの状態を確認すると以下のイベントが確認できます。
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 9d (x5 over 9d) default-scheduler 0/1 nodes are available: 1 node(s) had taints that the pod didn't tolerate.
nodeのtaintsをpodが許容できないということなので、nodeのtaints
をkubectl describe nodes
で確認します。
[root@k8smaster1 ~]# kubectl describe nodes
Name: k8smaster1
Roles: master
Labels: beta.kubernetes.io/arch=amd64
beta.kubernetes.io/os=linux
kubernetes.io/arch=amd64
kubernetes.io/hostname=k8smaster1
kubernetes.io/os=linux
node-role.kubernetes.io/master=
Annotations: kubeadm.alpha.kubernetes.io/cri-socket: /var/run/crio/crio.sock
node.alpha.kubernetes.io/ttl: 0
volumes.kubernetes.io/controller-managed-attach-detach: true
CreationTimestamp: Sat, 23 Nov 2019 19:58:55 +0900
Taints: node-role.kubernetes.io/master:NoSchedule
Taintsがnode-role.kubernetes.io/master:NoSchedule
のため、Labelsにmasterが指定されているこのノードにはPodをScheduleすることができません。
今回はシングルノードのMasterノードでデプロイさせたいので、このtaintsを削除します。
[root@k8smaster1 ~]# kubectl taint nodes k8smaster1 node-role.kubernetes.io/master:NoSchedule-
node/k8smaster1 untainted
これでPodがノードにScheduleされるようになりました。
コンテナランタイムcri-oにinsecure-registryの設定を追加
再度kubectl get pod
で確認すると以下となりImagePullBackOff
となっています。
[root@k8smaster1 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
my-release-mariadb-0 0/1 ImagePullBackOff 0 9d
my-release-redmine-859cf77958-n95j5 0/1 ImagePullBackOff 0 9d
kubectl desctibe pod <Pod名>
でEventを確認すると以下のエラーが確認できます。
Failed to pull image "private-registry.local/bitnami/mariadb:10.3.20-debian-9-r0": rpc error: code = Unknown desc = pinging docker registry returned: Get https://private-registry.local/v2/: dial tcp 192.168.0.101:443: connect: no route to host
コンテナイメージのpullの際に192.168.0.101:443
への接続ができていません。
情報
で示されているように192.168.0.101
はContainer-Registryです。
/etc/hosts
に192.168.0.101 private-registry.local
の記載があり、正しいことがわかります。
試しにDockerでImageのpullに失敗したコンテナイメージを手動でdocker pull private-registry.local/bitnami/mariadb:10.3.20-debian-9-r0
してみます。
この操作は正常にpullすることができ、docker images
でも正しくコンテナイメージがあることが確認できました。
[root@k8smaster1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
private-registry.local/bitnami/mariadb 10.3.20-debian-9-r0 36300b3aaaa0 3 weeks ago 289 MB
ここで再度k8s上のPodの状態を確認しますが、エラーに変化はありません。
[root@k8smaster1 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
my-release-mariadb-0 0/1 ImagePullBackOff 0 9d
my-release-redmine-859cf77958-n95j5 0/1 ImagePullBackOff 0 9d
さらに詳細にみるために全namespaceを対象にget podします。
[root@k8smaster1 ~]# kubectl get pod --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
default my-release-mariadb-0 0/1 ImagePullBackOff 0 9d
default my-release-redmine-859cf77958-n95j5 0/1 ImagePullBackOff 0 9d
kube-system coredns-74c9d4d795-hj9tn 1/1 Running 3 9d
kube-system coredns-74c9d4d795-l7949 0/1 Pending 0 9d
kube-system dns-autoscaler-7d95989447-crv67 1/1 Running 3 9d
kube-system kube-apiserver-k8smaster1 1/1 Running 3 9d
kube-system kube-controller-manager-k8smaster1 1/1 Running 3 9d
kube-system kube-proxy-mm8ld 1/1 Running 3 9d
kube-system kube-scheduler-k8smaster1 1/1 Running 3 9d
kube-system nodelocaldns-wgq47 1/1 Running 3 9d
kube-system weave-net-z97jl 2/2 Running 6 9d
RunningのPodがあるのに、docker images
では手動でpullしたイメージしかありませんでした。
何かおかしいですね。Dockerが使われていないのかもしれません。
k8sのコンテナランライムを確認するためにkubeletのユニットファイルを確認します。
ファイル/etc/systemd/system/kubelet.service
に記載の環境変数ファイル/etc/kubernetes/kubelet.env
には以下の記載があります。
KUBELET_ARGS="--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf \
--config=/etc/kubernetes/kubelet-config.yaml \
--kubeconfig=/etc/kubernetes/kubelet.conf \
--pod-infra-container-image=gcr.io/google_containers/pause-amd64:3.1 \
--container-runtime=remote \
--container-runtime-endpoint=/var/run/crio/crio.sock \
--runtime-cgroups=/systemd/system.slice \
--node-labels= "
container-runtime
にcrio
が指定されていることがわかります。
しっかりとサービスが動いていますね。
[root@k8smaster1 ~]# systemctl status crio
● crio.service - Open Container Initiative Daemon
Loaded: loaded (/usr/lib/systemd/system/crio.service; enabled; vendor preset: disabled)
Active: active (running) since Tue 2019-12-03 00:39:10 JST; 49min ago
Docs: https://github.com/kubernetes-sigs/cri-o
Main PID: 1076 (crio)
CGroup: /system.slice/crio.service
└─1076 /usr/bin/crio
crioはCRIなのでcrictl
による操作が可能です。
crictl images
の結果ではrunningだったPodのコンテナイメージがありました。
[root@k8smaster1 ~]# crictl images
IMAGE TAG IMAGE ID SIZE
docker.io/coredns/coredns 1.6.0 680bc53e5985f 42.3MB
docker.io/weaveworks/weave-kube 2.4.0 86ff1a48ce14d 134MB
docker.io/weaveworks/weave-npc 2.4.0 647ad6d59818d 49.5MB
gcr.io/google-containers/kube-apiserver v1.15.3 5eb2d3fc7a44e 208MB
gcr.io/google-containers/kube-controller-manager v1.15.3 e77c31de55475 160MB
gcr.io/google-containers/kube-proxy v1.15.3 232b5c7931462 84.3MB
gcr.io/google-containers/kube-scheduler v1.15.3 703f9c69a5d57 82.7MB
k8s.gcr.io/cluster-proportional-autoscaler-amd64 1.6.0 dfe4432cd2e2b 48.9MB
k8s.gcr.io/k8s-dns-node-cache 1.15.4 3f8330c31e7d5 64.3MB
k8s.gcr.io/pause 3.1 da86e6ba6ca19 747kB
gcr.io/google-containers/pause 3.1 da86e6ba6ca19 747kB
k8sのコンテナランタイムとしてcri-o
が動作していたので、80ポートでアクセスさせるために、cri-oのprivate-resigtry
へのinsecure-registryを追加しましょう。
214 # insecure_registries is used to skip TLS verification when pulling images.
215 insecure_registries = [
216 "10.233.0.0/24",
217 "private-registry.local"
218 ]
MariaDBのPersistentVolumeのディレクトリ権限(Permission)を修正
crioの設定を反映させた後、再度k8sのpodを確認します。
[root@k8smaster1 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
my-release-mariadb-0 0/1 Error 5 9d
my-release-redmine-859cf77958-n95j5 0/1 Running 1 9d
mariadbがエラーになっています。
コンテナの立ち上げは行われているので、コンテナのlogを確認します。
[root@k8smaster1 ~]# kubectl logs my-release-mariadb-0
16:43:21.98
16:43:21.98 Welcome to the Bitnami mariadb container
16:43:21.98 Subscribe to project updates by watching https://github.com/bitnami/bitnami-docker-mariadb
16:43:21.98 Submit issues and feature requests at https://github.com/bitnami/bitnami-docker-mariadb/issues
16:43:21.98 Send us your feedback at [email protected]
16:43:21.99
16:43:21.99 INFO ==> ** Starting MariaDB setup **
16:43:22.04 INFO ==> Validating settings in MYSQL_*/MARIADB_* env vars
16:43:22.04 INFO ==> Initializing mariadb database
mkdir: cannot create directory '/bitnami/mariadb/data': Permission denied
'/bitnami/mariadb/data': Permission denied
ディレクトリの権限不足のようですね。
/root/ictsc_problem_manifests
にあるk8sManifestを読み解くと、/var/opt/pv{1,2}
にPersistentVolumeがあることがわかります。
kubectl get pv
の結果よりmariaDBに対応するPathにchmod
で権限を付与します。
[root@k8smaster1 ictsc_problem_manifests]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv0001 20Gi RWO Recycle Bound default/data-my-release-mariadb-0 9d
pv0002 20Gi RWO Recycle Bound default/my-release-redmine 9d
[root@k8smaster1 ]# chmod -R 777 /var/opt/pv1/
再度k8sのPodの状況を確認すると正常にRedmineのPodが稼働していることが確認できました。
[root@k8smaster1 opt]# kubectl get pod
NAME READY STATUS RESTARTS AGE
my-release-mariadb-0 1/1 Running 9 9d
my-release-redmine-859cf77958-n95j5 1/1 Running 5 9d
VNCのブラウザからRedmineのページが閲覧できれば完了です。